(function($){

/*
var getMatrix = function(me){
		return {'matrix':me.data("matrix"),'rows':me.data("rows"),'cols':me.data("cols")};
	},

	getTableHolder = function(me){
		return me.find("div:eq(0)");
	},

	getBoxHolder = function(me){
		return me.find("div:eq(1)");
	},

	getBox = function(me){
		return me.find(">div:eq(1) > div:eq(0)");
	},



	storeMatrix = function(me, tmp_matrix){
		var  nc = 0,
			nr = 0,
			matrix = {};
		$.each( tmp_matrix, function(r,row){
				matrix[nr++] = {};
				nc=0;
				$.each(row, function(c,cell){
						matrix[nr-1][nc++] = cell;
					});
			});
		me.data("matrix", matrix);
		me.data("cols", nc);
		me.data("rows", nr);
	},

	setup_box = function(e){
		var me=e.data.me;
		getTableHolder(me).hide();
		getBoxHolder(me).show();

		getBox(me).selectBoxConfig( me.matrixGetCell(e.data.r,e.data.c) );
		me.data("curr_r", $(this).attr("myRow"));
		me.data("curr_c", $(this).attr("myCell") );
		return false;
	},

	delCell = function(e){
		var t,r = e.data.r,c = e.data.c,tmp,
		x=getMatrix(e.data.me);
		// c == none means remove a row not a column
		if ( c != "none" ){
			// remove the column BEFORE
			if ( c == "before" ){
				for (r=0; r < x.rows; r++){
					for (t = 0; t < x.cols; t++ ){
						x.matrix[r][t] = x.matrix[r][t+1];
					}
				}
			}
			else{ // remove the column AFTER
			}
			x.cols--;
		}
		else{ // delete a row
			if ( r == "before" ){
				for (t = 0; t < x.rows; t++ ){
					x.matrix[t] = x.matrix[t+1];
				}
			}
			else{ // delete aFTER
			}
			x.rows--;
		}
		e.data.me.data("matrix",x.matrix).data("rows",x.rows).data("cols",x.cols);
		buildMatrix(e.data.me);
		getRetRows(e.data.me).val( x.rows );
		getRetCols(e.data.me).val( x.cols );
		return false;
	},

	addCell = function(e){
		var t,r = e.data.r,c = e.data.c,tmp,
		x=getMatrix(e.data.me);
		// c == none means add a row not a columns
		if ( c != "none" ){
			// add the column BEFORE
			if ( c == "before" ){
				for (r=0; r < x.rows; r++){
					x.matrix[r][x.cols] = x.matrix[r][x.cols-1];
					for (t = x.cols-1; t>0; t-- ){
						x.matrix[r][t] = x.matrix[r][t-1];
					}
					x.matrix[r][0] = false;
				}
			}
			else{ // add the column AFTER
				for (r=0; r < x.rows; r++){
					x.matrix[r][x.cols] = false;
				}
			}
			x.cols++;
		}
		else{ // add a row
			// create the new row
			tmp = {};
			for (c=0; c < x.cols; c++ ){
				tmp[c] = false;
			}
			if ( r == "before" ){
				x.matrix[x.rows] = x.matrix[x.rows-1];
				for (t = x.rows-1; t>0; t-- ){
					x.matrix[t] = x.matrix[t-1];
				}
				x.matrix[0] = tmp;
			}
			else{ // insert aFTER
				x.matrix[x.rows] = tmp;
			}
			x.rows++;
		}
		e.data.me.data("matrix",x.matrix).data("rows",x.rows).data("cols",x.cols);
		buildMatrix(e.data.me);
		getRetRows(e.data.me).val( x.rows );
		getRetCols(e.data.me).val( x.cols );
		return false;
	},



	matrixCell = function( me, r, c ){
		var id = me.matrixGetCell(r,c);
		var button = $('<button>'+matrixCell.titles[id]+'</button>');
	
		button.bind("click",{'me':me,'r':r,'c':c}, setup_box );
		button.attr("myRow", r);
		button.attr("myCell",c);
	
		if ( !matrixCell.titles[id] ){
				me.JsonRequest( {id:"AtomInfoRequest", data:{'id':id,'title':true},cb:function(d,e){
											button.html(d.title);
											matrixCell.titles[id] = d.title;
										}});
		}
		return $('<td class="matrix">').append( button );
	},

	buildMatrix = function(me){
		var x=getMatrix(me),r,c,row,xtd,
			table = getTable(me);
		// Clear up the table contents, if any
		table.empty();
		// Append the button to add a row BEFORE the table (only if we have > 0 rows)
		if ( x.rows > 0 ){
			table.append($('<tr>').append(
							$('<td colspan="'+(x.cols+2)+'" class="matrix_add">').append(
								matrixAdd(me,"before","none")).append(
								matrixDel(me,"before","none"))));
		}
		// draw the table
		for (r = 0; r < x.rows; r++ ){
			table.append( row = $('<tr class="matrix">') );

			// append a button to add a column in front of the matrix (only if we have > 0 columns)
			if ( (r===0) && (x.cols > 0) ){
				row.append( $('<td class="matrix_add" rowspan="'+x.rows+'">').append(
									matrixAdd(me,"none","before")).append(
									matrixDel(me,"none","before")) );
			}
			// Draw all the cells
			for (c = 0; c < x.cols; c++ ){
				row.append( matrixCell( me, r, c  ) );
			}
			// append a button to add a column on the right of the matrix
			if ( r === 0 ){
				row.append( xtd = $('<td class="matrix_add" rowspan="'+x.rows+'">').append(
									matrixAdd(me,"none","after")) );
				if ( x.cols > 0 )
					xtd.append( matrixDel(me,"none","after") );
			}
			
		}
		// Apend the button to add a row AFTER the matrix
		table.append( $('<tr>').append(
							xtd = $('<td colspan="'+(x.cols+2)+'" class="matrix_add">').append(
								matrixAdd(me,"after","none")) ) );
		if ( x.rows > 0 )
			xtd.append( matrixDel(me,"after","none") );

	},

	saveMatrix = function(me){
		var r,c,x=getMatrix(me),ret={};
		for ( r = 0; r < x.rows; r++ ){
			for (c=0; c < x.cols; c++ ){
				ret[ "r"+r+"c"+c ] = x.matrix[r][c];
			}
		}
		getRetMatrix(me).val( $.param( ret ) );
	};
	matrixCell.titles = {};



	
$.fn.matrixGetCell = function(r,c){
	var x = getMatrix($(this));
	if ( ( (r>=0)&&(r<x.rows) ) && ( (c>=0)&&(c<x.cols) ) ){
		return x.matrix[r][c];
	}
	return false;
};

$.fn.matrixInit = function( matrix ){
	this.each(function() {
		var $this = $(this);
		// Convert the matrix and store it inside the object
		storeMatrix($this, matrix);
		// Build the HTML matrix
		buildMatrix($this);
		//
		saveMatrix($this);
		// Associate the update event to reflect a change from the selectBox to the stored matrix
		$this.bind("update", $this, function(e){
				var me = e.data;
				var atom_id = getBox(me).selectBoxGet(),
					c = me.data("curr_c"),
					r = me.data("curr_r"),
					x = getMatrix(me);
				x.matrix[r][c] = atom_id;
				me.data("matrix", x.matrix);
				buildMatrix(me);
				getTableHolder(me).show();
				getBoxHolder(me).hide();
				saveMatrix(me);
				return false;
			});
		// Associate the cancel event to reflect a nonchange from the selectBox to the stored matrix
		$this.bind("cancel", $this, function(e){
				var me = e.data;
				getTableHolder(me).show();
				getBoxHolder(me).hide();
				return false;
			});
	});
};


xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


var getSampleTd = function(me){
		return me.find(">span:eq(0)");
	},

	getAtomManager = function(me){
		return me.find(">div:eq(1)>div.atom_manager");
	},

	getTable = function(me){
		return me.find("table:eq(0)");
	},

	getAtoms = function(me){
		return me.find("input[type=hidden][name=matrix_return]");
	},

	getRows = function(me){
		return me.find("input[type=hidden][name=rows_return]");
	},

	getCols = function(me){
		return me.find("input[type=hidden][name=cols_return]");
	},

	setTitle = function(td,atom_id){
		var applyTitle = function(t,title){
				t.find(">span:eq(0)").html(title);
			};
		if ( setTitle.titles[atom_id] ){
			applyTitle(td,setTitle.titles[atom_id]);
		}
		else {
			td.one("json_request_completed",{t:td,id:atom_id}, function(e,d){
													setTitle.titles[e.data.id] = d.title;
													applyTitle( e.data.t, d.title );
												});
			td.jsonRequest("AtomInfoRequest",{'id':atom_id,'title':true},"post");
		}
	},

	addCell = function(e){
		var r=e.data.r,c=e.data.c,me=e.data.me;

		if ( r == false ){
			
		}
		else if ( c == false ){

		}
		else{
			alert("Both r and c not false?");
		}
	},

	delCell = function(e){
		alert(Core.Dump(e.data));
	},

	getAtomId = function(me,r,c){
		var atoms = getAtoms(me).val().split(","),
			rows = getRows(me).val(),
			cols = getCols(me).val();
		if ( (r>=0) && (r<rows ) ){
			if ( (c>=0) && (c<cols) ){
				return atoms[ r*cols+c ];
			}
		}
	},

	buildRow = function(me,r, rows){
		var	c,cols = getCols(me),sample = getSampleTd(me),
			td,tr = $('<tr></tr>'),
			matrixAdd = function(me,r,c){
				var btn = $('<button><img src="/Theme/default/icons/plus.gif" alt="[+]"></button>');
				btn.bind("click", {'me':me,'r':r,'c':c}, addCell );
				return btn;
			},
			matrixDel = function(me,r,c){
				var btn = $('<button><img src="/Theme/default/icons/minus.gif" alt="[-]"></button>');
				btn.bind("click", {'me':me,'r':r,'c':c}, delCell );
				return btn;
			};

		if ( (r == -1)  ){
			tr.append( td = $("<td rowspan='"+(rows+2)+"'></td>") );
			td.append( matrixAdd(me,false,-1) );
			tr.append( td = $("<td colspan='"+cols+"'></td>") );
			td.append( matrixAdd(me,-1,false) );
			tr.append( td = $("<td rowspan='"+(rows+2)+"'></td>") );
			td.append( matrixAdd(me,false,cols) );
		}
		else if ( (r == rows ) ){
			tr.append( td = $("<td colspan='"+cols+"'></td>") );
			td.append( matrixAdd(me,rows,false) );
		}
		else{
			for (c = 0; c < cols; c++){
				td = sample.clone(true);
				td.show();
				td.attr("my_row", r).attr("my_col", c);
				setTitle(td, getAtomId(me,r,c) );
				tr.append(td);
			}
		}
		return tr;
	},

	buildMatrix = function(me){
		var r,rows = getRows(me).val(),table = getTable(me);
		table.empty();
		alert(rows);
		for ( r = -1; r <= rows; r++ ){
			table.append( buildRow(me, r,rows) );
		}
	},

	setAtomId = function(me,r,c,atom_id){
		var atoms = getAtoms(me).val().split(","),
			rows = getRows(me).val(),
			cols = getCols(me).val();
		if ( (r>=0) && (r<rows ) ){
			if ( (c>=0) && (c<cols) ){
				atoms[ r*cols+c ] = atom_id;
			}
		}
		getAtoms(me).val( atoms.join(",") );
		buildMatrix(me);
	};
setTitle.titles = {};

Core.ObjectTypes["div.box_matrix"] = function(){

	var me = $(this),
		sample = getSampleTd( me );

	sample.find(">button:eq(0)").bind("click", me,
			function(e){
				var me=e.data,
					atom_id = getAtomId(me, $(this).attr("my_row"),$(this).attr("my_col") ),
					r = $(this).attr("my_row"),
					c = $(this).attr("my_col");
				me.find(">div:eq(0)").hide();
				me.find(">div.eq(1)").show();
				alert(atom_id);
				getAtomManager(me).atomManagerSet( atom_id );
				me.attr("my_row", r);
				me.attr("my_col", c);
			});

	getAtomManager(me).bind("atom_selected", me, function(e,atom_id){
				var me = e.data;
				setAtomId( me, me.attr("curr_row"), me.attr("curr_col"), atom_id);
			});

	sample.find(">button:eq(1)").bind("click", me, 
			function(e){
				var me = e.data,
					r = $(this).attr("my_row"),
					c = $(this).attr("my_col");
				setAtomId(me,r,c,false);
			});

	me.find(">div:eq(1)>button:last").bind("click", me, 
			function(e){
				var me=e.data;
				me.find(">div:eq(0)").show();
				me.find(">div.eq(1)").hide();
			});
	buildMatrix(me);

};



/*function matrixUpdate(e){
	$('#'+e.data).trigger("update");
	return false;
}
function matrixCancel(e){
	$('#'+e.data).trigger("cancel");
	return false;
}*/

Core.ObjectTypes["div.box_matrix"] = function(){
	var me = $(this);

	me.find(">div:eq(1)").sortable();


}(jQuery));